<?php

// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * This script fetches files from the dataroot directory
 *
 * TODO: Blog attachments do not have access control implemented - anybody can read them!
 *       It might be better to move the code to separate file because the access
 *       control is quite complex - see bolg/index.php
 * Syntax:      file.php/courseid/dir/dir/dir/filename.ext
 *              file.php/courseid/dir/dir/dir/filename.ext?forcedownload=1 (download instead of inline)
 *              file.php/courseid/dir (returns index.html from dir)
 * Workaround:  file.php?file=/courseid/dir/dir/dir/filename.ext
 * Test:        file.php/testslasharguments
 *
 * @package   block_email_list
 * @author    Tony Mas <toni.mas@uib.dot.es>
 * @copyright 2009 by <toni.mas at uib dot es>
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AFFERO GENERAL PUBLIC LICENSE
 */

require_once('../../../config.php');
require_once('../../../lib/filelib.php');
// eMail - Toni Mas
require_once($CFG->dirroot.'/blocks/email_list/email/email.class.php'); 			// Alert! FIXME

if (!isset($CFG->filelifetime)) {
    $lifetime = 86400;     // Seconds for files to remain in caches
} else {
    $lifetime = $CFG->filelifetime;
}

// disable moodle specific debug messages
disable_debugging();

$relativepath = get_file_argument('file.php');
$forcedownload = optional_param('forcedownload', 0, PARAM_BOOL);

// relative path must start with '/', because of backup/restore!!!
if (!$relativepath) {
    error('No valid arguments supplied or incorrect server configuration');

} else if ($relativepath{0} != '/') {
    error('No valid arguments supplied, path does not start with slash!');
}

$pathname = $CFG->dataroot.$relativepath;

// extract relative path components
$args = explode('/', trim($relativepath, '/'));

if (count($args) == 0) { // always at least courseid, may search for index.html in course root
    error('No valid arguments supplied');
}

// security: limit access to existing course subdirectories

if (($args[0]!='blog') and (!$course = $DB->get_record('course', array('id' => (int) $args[0])))) {
    error('Invalid course ID');
}

// security: prevent access to "000" or "1 something" directories
// hack for blogs, needs proper security check too
if (($args[0] != 'blog') and ($args[0] != $course->id)) {
    print_error('Invalid course ID');
}

// security: login to course if necessary
// Note: file.php always calls require_login() with $setwantsurltome=false
//       in order to avoid messing redirects. MDL-14495
if ($args[0] == 'blog') {

    if (empty($CFG->bloglevel)) {
        error('Blogging is disabled!');

    } else if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) {
        require_login(0, true, null, false);

    } else if ($CFG->forcelogin) {
        require_login(0, true, null, false);
    }

} else if ($course->id != SITEID) {
    require_login($course->id, true, null, false);

} else if ($CFG->forcelogin) {

    if (!empty($CFG->sitepolicy)
        and ($CFG->sitepolicy == $CFG->wwwroot.'/file.php'.$relativepath
        or $CFG->sitepolicy == $CFG->wwwroot.'/file.php?file='.$relativepath)) {
        //do not require login for policy file
    } else {
        require_login(0, true, null, false);
    }
}

// security: only editing teachers can access backups
if ((count($args) >= 2) and (strtolower($args[1]) == 'backupdata')) {

    if (!has_capability('moodle/site:backup', context_course::instance($course->id))) {
        print_error('Access not allowed');
    } else {
        $lifetime = 0; //disable browser caching for backups
    }
}

if (is_dir($pathname)) {

    if (file_exists($pathname.'/index.html')) {
        $pathname = rtrim($pathname, '/').'/index.html';
        $args[] = 'index.html';

    } else if (file_exists($pathname.'/index.htm')) {
        $pathname = rtrim($pathname, '/').'/index.htm';
        $args[] = 'index.htm';

    } else if (file_exists($pathname.'/Default.htm')) {
        $pathname = rtrim($pathname, '/').'/Default.htm';
        $args[] = 'Default.htm';
    } else {
        // security: do not return directory node!
        not_found($course->id);
    }
}

// security: teachers can view all assignments, students only their own
if ((count($args) >= 3)
 && (strtolower($args[1]) == 'moddata')
 && (strtolower($args[2]) == 'assignment')) {

    $lifetime = 0;  // do not cache assignments, students may reupload them

    if (!has_capability('mod/assignment:grade', context_course::instance($course->id))
     && $args[4] != $USER->id) {
        print_error('Access not allowed');
    }
}

// Antoni Mas: eMail Security
if ( strtolower($args[3]) == 'email') {
    // Get mail
    $email = new eMail();
    $email->set_email($args[5]);

    if (! $email->can_readmail($USER) ) {
        print_error('Access not allowed');
    }
}

// security: force download of all attachments submitted by students
if ((count($args) >= 3)
    and (strtolower($args[1]) == 'moddata')
    and ((strtolower($args[2]) == 'forum')
    or (strtolower($args[2]) == 'assignment')
    or (strtolower($args[2]) == 'data')
    or (strtolower($args[2]) == 'glossary')
    or (strtolower($args[2]) == 'wiki')
    or (strtolower($args[2]) == 'exercise')
    or (strtolower($args[2]) == 'workshop'))) {
    $forcedownload  = 1; // force download of all attachments
}

if ($args[0] == 'blog') {
    $forcedownload  = 1; // force download of all attachments
}

// security: some protection of hidden resource files
// warning: it may break backwards compatibility
if ((!empty($CFG->preventaccesstohiddenfiles))
    and (count($args) >= 2)
    // do not block files from other modules!
    and (!(strtolower($args[1]) == 'moddata' and strtolower($args[2]) != 'resource'))
    and (!has_capability('moodle/course:viewhiddenactivities', context_course::instance($course->id)))) {

    $rargs = $args;
    array_shift($rargs);
    $reference = implode('/', $rargs);

    $sql = 'SELECT COUNT(r.id) ' .
           'FROM {resource} r, ' .
                '{course_modules} cm, ' .
                '{modules} m ' .
           'WHERE r.course    = ? ' .
             'AND m.name      = ? ' .
             'AND cm.module   = m.id ' .
             'AND cm.instance = r.id ' .
             'AND cm.visible  = 0 ' .
             'AND r.type      = ? ' .
             'AND r.reference = ?';
    $values = array($course->id, 'resource', 'file', $reference);

    if ($DB->count_records_sql($sql, $values)) {
        error('Access not allowed');
    }
}

// check that file exists
if (!file_exists($pathname)) {
    not_found($course->id);
}

// ========================================
// finally send the file
// ========================================
session_write_close(); // unlock session during fileserving
$filename = $args[count($args)-1];
send_file($pathname, $filename, $lifetime, $CFG->filteruploadedfiles, false, $forcedownload);

/**
 * Prints a not found error
 *
 * @param int $courseid The course id to print the error for
 * @return void
 * @uses $CFG
 */
function not_found($courseid) {
    global $CFG;
    header('HTTP/1.0 404 not found');
    //this is not displayed on IIS??
    print_error('filenotfound', 'error', $CFG->wwwroot.'/course/view.php?id='.$courseid);
}